<template>
  <div>
    <div>组件</div>
    <div>
      <a-button type="primary" @click="changeComponent">切换</a-button>
      <a-divider></a-divider>
      <a-button type="primary" @click="loadComponent">异步组件</a-button>
    </div>
    <div>
      <component :is="Mycomponent"></component>
    </div>
  </div>
</template>

<script>
import { defineAsyncComponent, shallowRef } from "vue";
export default {
  data() {
    return {
      /**
       * shallowRef 和 ref() 不同，浅层 ref 的内部值将会原样存储和暴露，并且不会被深层递归地转为响应式。只有对 .value 的访问是响应式的。
       * shallowRef() 常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。
       */
      Mycomponent: shallowRef(
        defineAsyncComponent(() => import("./LoadComponentVueA.vue"))
      ),
      status: false,
    };
  },
  methods: {
    changeComponent() {
      if (this.status) {
        // import("./LoadComponentVueA.vue").then((comp) => {
        //   this.Mycomponent = comp.default;
        // });
        this.Mycomponent = shallowRef(
          defineAsyncComponent(() => import("./LoadComponentVueA.vue"))
        );
      } else {
        // import("./LoadComponentVueB.vue").then((comp) => {
        //   this.Mycomponent = comp.default;
        // });
        this.Mycomponent = shallowRef(
          defineAsyncComponent(() => import("./LoadComponentVueB.vue"))
        );
      }
      this.status = !this.status;
    },
    loadComponent() {
      // 展示 defineAsyncComponent 的完整用法
      const AsyncComp = defineAsyncComponent({
        // 加载函数
        loader: () => {
          /**
           * 支持直接导入
           */
          // import("./LoadAsyncVue.vue")
          /**
           * 支持 Promise 形式返回
           */
          // eslint-disable-next-line no-unused-vars
          return new Promise((resolve, reject) => {
            const Comp = import("./LoadAsyncVue.vue");
            resolve(Comp);
          });
        },
        // 加载异步组件时使用的组件
        loadingComponent: import("./LoadComponentVueA.vue"),
        // 展示加载组件前的延迟时间，默认为 200ms
        delay: 1000,

        // 加载失败后展示的组件
        errorComponent: import("./LoadComponentVueB.vue"),
        // 如果提供了一个 timeout 时间限制，并超时了
        // 也会显示这里配置的报错组件，默认值是：Infinity
        timeout: 3000,
      });
      this.Mycomponent = AsyncComp;
    },
  },
};
</script>

<style></style>
